<html>
<head><meta charset="utf-8"><title>Placement new and heap allocation of large struct · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html">Placement new and heap allocation of large struct</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="199445753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199445753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199445753">(Jun 02 2020 at 02:53)</a>:</h4>
<p>I think I've found a way to introduce C++ placement new to the standard library:</p>
<div class="codehilite"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">placement_new</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">F</span>: <span class="nb">FnOnce</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">place</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">ctor</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">std</span>::<span class="n">intrinsics</span>::<span class="n">move_val_init</span><span class="p">(</span><span class="n">place</span><span class="p">,</span><span class="w"> </span><span class="n">ctor</span><span class="p">());</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>This with the RVO will guarantee that T is written directly into the place without allocating on stack.</p>
<p>We could use it to allocate a large struct on heap without box syntax:</p>
<div class="codehilite"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">box_with</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">F</span>: <span class="nb">FnOnce</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ctor</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">boxed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new_uninit</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="n">placement_new</span><span class="p">(</span><span class="n">boxed</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">ctor</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">boxed</span><span class="p">.</span><span class="n">assume_init</span><span class="p">()</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="199445845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199445845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199445845">(Jun 02 2020 at 02:55)</a>:</h4>
<p>Last time we tried placement-in, we decided that any guarantees based on optimisations is not feasible.</p>



<a name="199445923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199445923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199445923">(Jun 02 2020 at 02:57)</a>:</h4>
<p>This does not depend on any LLVM optimisation and  is available in -Copt-level=0</p>



<a name="199445974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199445974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199445974">(Jun 02 2020 at 02:58)</a>:</h4>
<p>You can always construct an example contrived enough that some implementation of RVO would not be able to handle.</p>



<a name="199445982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199445982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199445982">(Jun 02 2020 at 02:58)</a>:</h4>
<p>or more generally some implementation of any optimisation.</p>



<a name="199446098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199446098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199446098">(Jun 02 2020 at 03:01)</a>:</h4>
<p>According to the current MIR. I believe as long as the return value is directly constructed and returned it, it is guaranteed to occupy _0 without any optimisation?</p>



<a name="199495291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199495291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199495291">(Jun 02 2020 at 14:02)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct/near/199445845">said</a>:</p>
<blockquote>
<p>Last time we tried placement-in, we decided that any guarantees based on optimisations is not feasible.</p>
</blockquote>
<p>To be fair, the last time we tried placement-in, "we" (really just niko and I if I recall correctly) tried a strategy of making it largely syntactic sugar; the relying on optimization was sort of hoping the whole pipeline from the AST down would optimize things well</p>



<a name="199495709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199495709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199495709">(Jun 02 2020 at 14:05)</a>:</h4>
<p>if I were to attack the problem again today, I probably try an approach that would try to at least make some guarantees about the <em>MIR</em> that was generated, which we can control</p>



<a name="199495776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199495776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199495776">(Jun 02 2020 at 14:05)</a>:</h4>
<p>(and might be "good enough")</p>



<a name="199508443"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199508443" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199508443">(Jun 02 2020 at 15:21)</a>:</h4>
<p>we can add guaranteed optimizations at the MIR level that report errors when they fail</p>



<a name="199523911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199523911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199523911">(Jun 02 2020 at 17:13)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> could you share me a link of the last try?</p>



<a name="199524045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524045">(Jun 02 2020 at 17:14)</a>:</h4>
<p>I'm referring to the placement-in syntax that was part of nightly for a long while before it was removed.  Let me find the PR that removed it.</p>



<a name="199524134"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524134" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524134">(Jun 02 2020 at 17:15)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/27779">https://github.com/rust-lang/rust/issues/27779</a></p>



<a name="199524153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524153">(Jun 02 2020 at 17:15)</a>:</h4>
<p>no wait</p>



<a name="199524170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524170">(Jun 02 2020 at 17:15)</a>:</h4>
<p>this PR removed it: <a href="https://github.com/rust-lang/rust/pull/48333">https://github.com/rust-lang/rust/pull/48333</a></p>



<a name="199524233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524233">(Jun 02 2020 at 17:16)</a>:</h4>
<p>this comment summarized <em>why</em> we removed it: <a href="https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911">https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911</a></p>



<a name="199524334"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199524334" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199524334">(Jun 02 2020 at 17:17)</a>:</h4>
<p>Thx</p>



<a name="199527069"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199527069" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199527069">(Jun 02 2020 at 17:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct/near/199495709">said</a>:</p>
<blockquote>
<p>if I were to attack the problem again today, I probably try an approach that would try to at least make some guarantees about the <em>MIR</em> that was generated, which we can control</p>
</blockquote>
<p>The real problem was with us trying to handle arbitrary expressions on the RHS of the operator. Gary's proposal is pretty much the same, except this time it pulls RVO into equation to help with the problem of function call expressions. And wraps the previously inline arbitrary RHS into a function call through a <code>FnOnce</code>. RVO and the function call cancel each other and you still end up with a place and an arbitrary RHS. </p>
<p>The reason C++ is able to guarantee in-place construction is because they pass the <code>this</code> pointers/places all the way down their constructor stack and the constructor code generally is written to boil down to the most basic assignment statements to fields on said place. In the instances where the assignments are not trivial, you must use placement-new (<code>new (place) Something { ... }</code>) in the smaller constructors to retain the guarantee all the way down. And majority of library code don’t and won’t do that.</p>



<a name="199527296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199527296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199527296">(Jun 02 2020 at 17:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct/near/199527069">said</a>:</p>
<blockquote>
<p>And majority of library code don’t and won’t do that.</p>
</blockquote>
<p>Are you saying that is true of C++ library code? Or are you saying that Rust library code would not shift to do that?</p>



<a name="199527331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199527331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199527331">(Jun 02 2020 at 17:40)</a>:</h4>
<p>(I'm not arguing against what you're saying. Just want clarification.)</p>



<a name="199527462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199527462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199527462">(Jun 02 2020 at 17:41)</a>:</h4>
<p>The statement is generally true of C++ code I have seen in the wild.</p>



<a name="199528254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199528254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199528254">(Jun 02 2020 at 17:48)</a>:</h4>
<p>Okay, I briefly read through that PR and some relevant RFCs. So the issue is that when constructing a struct, we construct fields to a temporary place first and then move it into the struct. With RVO, the struct itself isn't placed on the stack anymore, but the temporaries still are, so nested large structs still don't work.</p>



<a name="199528355"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199528355" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199528355">(Jun 02 2020 at 17:49)</a>:</h4>
<p>I believe we fields on the stack first in the MIR to cope with stack unwind?</p>



<a name="199528615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199528615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199528615">(Jun 02 2020 at 17:51)</a>:</h4>
<p>Failing on "guaranteed" optimizations, I feel, is another pit hole we shouldn’t put our feet into – it effectively stabilizes the fact that an arbitrarily complex expression satisfies some codegen condition. While it is not a problem for the cases we consciously handle, it would also accidentally cover (especially in combination with other optimizations) expressions we couldn’t possibly anticipate ahead of time. When guarantees for unanticipated cases break because other optimisations change in behaviour everything starts exploding.</p>



<a name="199529140"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199529140" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199529140">(Jun 02 2020 at 17:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="303710">Gary Guo</span> <a href="#narrow/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct/near/199528355">said</a>:</p>
<blockquote>
<p>I believe we fields on the stack first in the MIR to cope with stack unwind?</p>
</blockquote>
<p>It also has to do with eager vs lazy space allocation for values. In particular eager allocation has worse peak memory use characteristics, but is also necessary to guarantee placement-in. For that reason placement-in/new is a syntactically separate construct.</p>



<a name="199530208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530208">(Jun 02 2020 at 18:03)</a>:</h4>
<p>I think in the MIR we always <del>declare</del> make live a place eagerly. For code like <code>let a = (b, c)</code> we are doing <code>let a; let _1; let _2; _1 = b; _2 = c; a.0 = move _1;  a.1 = move _2;</code> To me it seems we some tweaks we can just do <code>let a; a.0 = b; a.1 = c;</code></p>



<a name="199530361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530361">(Jun 02 2020 at 18:04)</a>:</h4>
<p>I’m pretty sure we predeclare all of the places at the "beginning" of the function, but that has no influence on the place's lifetime.</p>



<a name="199530379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530379">(Jun 02 2020 at 18:04)</a>:</h4>
<p>Space for locals is allocated with <code>StorageLive</code>, not by declaring a local (unless there are no storage statements at all)</p>



<a name="199530498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530498">(Jun 02 2020 at 18:05)</a>:</h4>
<p>I know, and the <code>StorageLive</code> of <code>a</code> is before both <code>_1</code> and <code>_2</code>.</p>



<a name="199530670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530670">(Jun 02 2020 at 18:07)</a>:</h4>
<p>I can’t remember what particular example eddyb was fond of to demonstrate this kind of issue very clearly.</p>



<a name="199530888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199530888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199530888">(Jun 02 2020 at 18:08)</a>:</h4>
<p><span class="user-mention" data-user-id="303710">@Gary Guo</span> Sounds like your example is easily handled via the destination propagation optimization, but that doesn't give any guarantees that it'll happen</p>



<a name="199545799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199545799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199545799">(Jun 02 2020 at 20:06)</a>:</h4>
<p>Yes, this optimisation doesn't happen in debug mode currently. And I agree with nagisa that we shouldn't depend on some optimisation that may or may not happen.</p>
<p>I think the better way is to guarantee that the MIR is constructed directly into the "optimised" format of my example. For example, we might say that assignment to a uninitialised place will guarantee that the space will be used directly without any intermediate places being used.</p>



<a name="199666548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Placement%20new%20and%20heap%20allocation%20of%20large%20struct/near/199666548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Placement.20new.20and.20heap.20allocation.20of.20large.20struct.html#199666548">(Jun 03 2020 at 19:39)</a>:</h4>
<p>I have a very naive idea about library-level placement new at <a href="https://github.com/dtolnay/request-for-implementation/issues/46">https://github.com/dtolnay/request-for-implementation/issues/46</a> .</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>